home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / mailutil.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  8KB  |  368 lines

  1. /*    General Mail Utilities
  2.  *    culled from other files to reduce unnecessary cross references.
  3.  *    This material is believed to be in the public domain.
  4.  */
  5. #include <stdio.h>
  6. #ifdef MSDOS
  7. #include <io.h>
  8. #endif
  9. #include <fcntl.h>
  10. #include <ctype.h>
  11. #include "global.h"
  12. #include "config.h"
  13. #include "socket.h"
  14. #include "mailutil.h"
  15. #include "smtp.h"
  16. #include "files.h"
  17.  
  18. #ifdef linux
  19. extern int close __ARGS((int)); /* this should be in fcntl.h... */
  20. extern int unlink __ARGS((char *)); /* can't include unistd.h, collisions */
  21. #endif
  22.  
  23. /*     Jan 92    Bill Simpson
  24.  *        The following routines were combined from smtpserv.c,
  25.  *        pop3cli.c and nntpcli.c
  26.  */
  27.  
  28. #ifdef POP3CLIENT
  29.  
  30. /* Receive message from socket, copying to file.
  31.  * Returns number of lines received, -1 indicates error
  32.  */
  33. int
  34. recvmail(s,buf,len,fp,trace)
  35. int s;        /* Socket index */
  36. char *buf;    /* Line buffer */
  37. unsigned len;    /* Length of buffer */
  38. FILE *fp;    /* File to copy into */
  39. int trace;    /* to trace or not to trace */
  40. {
  41.     int lines = 0;
  42.  
  43.     while (recvline(s,buf,len) != -1) {
  44.         register char *p = buf;
  45.  
  46.         if (trace >= 4)
  47.             log(s,"<==%s", buf);
  48.  
  49.         /* check for end of message . or escaped .. */
  50.         if (*p == '.') {
  51.             if (*++p == '\n') {
  52.                 if (trace >= 3)
  53.                     log(s,"received %d lines", lines);
  54.                 return lines;
  55.             } else if ( *p != '.' ) {
  56.                 p--;
  57.             }
  58.         } else if (strncmp(p,"From ",5) == 0) {
  59.             /* for UNIX mail compatiblity */
  60.             (void) putc('>',fp);
  61.         }
  62.         /* Append to data file */
  63.         fputs(p,fp);
  64.         ++lines;
  65.     }
  66.     if ( trace >= 1 )
  67.         log(s,"receive error after %d lines", lines);
  68.     return -1;
  69. }
  70. #endif
  71.  
  72. #if (defined(POP2CLIENT) || defined(POP3CLIENT))
  73.  
  74. /* Copy from the work file into the mailbox.
  75.  * -1 indicates error
  76.  */
  77. int
  78. copymail(spoolarea,filename,buf,len,wfp,trace)
  79. char *spoolarea;
  80. char *filename; /* Target Filename */
  81. char *buf;    /* Line buffer */
  82. unsigned len;    /* Length of buffer */
  83. FILE *wfp;    /* File to copy from */
  84. int trace;      /* to trace or not to trace */
  85. {
  86.     FILE *mfp = NULLFILE;
  87.  
  88.     while (mlock(spoolarea,filename)) {
  89.         pause(10000L);    /* 10 seconds */
  90.     }
  91.  
  92.     sprintf(buf,"%s/%s.txt",spoolarea,filename);
  93.  
  94.     if ((mfp = fopen(buf,APPEND_TEXT)) == NULL) {
  95.         if ( trace >= 1 )
  96.             log(-1,"*** Unable to open %s!!!\n", buf);
  97.         tprintf("\n*** Unable to open %s!!!\n", buf);
  98.         rmlock(spoolarea,filename);
  99.         return -1;
  100.     }
  101.  
  102.     rewind(wfp);
  103.  
  104.     while ( fgets(buf,(int)len,wfp) != NULLCHAR ) {
  105.         fputs(buf,mfp);
  106.         pwait(NULL);    /* give other processes time in long copy */
  107.     }
  108.     fclose(mfp);
  109.  
  110.     rmlock(spoolarea,filename);
  111.     return 0;
  112. }
  113. #endif
  114.  
  115.  
  116. /*     Jan 92    Bill Simpson
  117.  *         The following routines were extracted from smtpserv.c
  118.  *        and smtpcli.c, since they are used from several places.
  119.  */
  120.  
  121. /* create mail lockfile */
  122. int
  123. mlock(dir,id)
  124. char *dir,*id;
  125. {
  126.     char lockname[FILE_PATH_SIZE];
  127.     int fd;
  128. #ifdef notdef
  129. /* This is NOT a good idea ! This prevents all mailfiles in subdirs
  130.  * to be accessed; thus no nntp access etc... - WG7J
  131.  */
  132.  
  133. #ifdef    MSDOS
  134.     if(strlen(id) > 8) {        /* truncate long filenames */
  135.         id[8] = '\0';
  136.         if(id[7] == '/')
  137.             id[7] = '\0';
  138.     }
  139. #endif
  140. #endif
  141.  
  142.     /* Try to create the lock file in an atomic operation */
  143.     sprintf(lockname,"%s/%s.lck",dir,id);
  144. #ifdef        AMIGA
  145.     /* don't ask, really, just don't ask... I'd do file locking on
  146.      * an Amiga much more differently than this.
  147.      */
  148.     if(access(lockname, 0) == 0)
  149.         return -1;
  150. #endif
  151.     if((fd = open(lockname, O_WRONLY|O_EXCL|O_CREAT,0600)) == -1)
  152.         return -1;
  153.     close(fd);
  154.     return 0;
  155. }
  156.  
  157.  
  158. /* remove mail lockfile */
  159. int
  160. rmlock(dir,id)
  161. char *dir,*id;
  162. {
  163.     char lockname[FILE_PATH_SIZE];
  164.  
  165. #ifdef notdef /* See mlock() above - WG7J */
  166. #ifdef  MSDOS
  167.     if(strlen(id) > 8) {        /* truncate long filenames */
  168.         id[8] = '\0';
  169.         if(id[7] == '/')
  170.             id[7] = '\0';
  171.     }
  172. #endif
  173. #endif
  174.  
  175.     sprintf(lockname,"%s/%s.lck",dir,id);
  176.     return(unlink(lockname));
  177. }
  178.  
  179.  
  180. /* Given a string of the form <user@host>, extract the part inside the
  181.  * angle brackets and return a pointer to it.
  182.  */
  183. char *
  184. getname(cp)
  185. register char *cp;
  186. {
  187.     register char *cp1;
  188.  
  189.     if ((cp = strchr(cp,'<')) == NULLCHAR)
  190.         return NULLCHAR;
  191.     cp++;    /* cp -> first char of name */
  192.     if ((cp1 = strchr(cp,'>')) == NULLCHAR)
  193.         return NULLCHAR;
  194.     *cp1 = '\0';
  195.     return cp;
  196. }
  197.  
  198.  
  199. /*      Jan 92  Bill Simpson
  200.  *        The following routines were extracted from mailbox.c,
  201.  *        since they are used from several places.
  202.  */
  203.  
  204.  
  205. /* Parse a string in the "Text: Text <user@host>" or "Text: user@host (Text)"
  206.  * formats for the address user@host.
  207.  */
  208. char *
  209. getaddress(string,cont)
  210. char *string;
  211. int cont;        /* true if string is a continued header line */
  212. {
  213.     char *cp, *ap = NULLCHAR;
  214.     int par = 0;
  215.  
  216.     if((cp = getname(string)) != NULLCHAR) /* Look for <> style address */
  217.         return cp;
  218.  
  219.     cp = string;
  220.     if(!cont)
  221.         if((cp = strchr(string,':')) == NULLCHAR)    /* Skip the token */
  222.             return NULLCHAR;
  223.         else
  224.             ++cp;
  225.     for(; *cp != '\0'; ++cp) {
  226.         if(par && *cp == ')') {
  227.             --par;
  228.             continue;
  229.         }
  230.         if(*cp == '(')        /* Ignore text within parenthesis */
  231.             ++par;
  232.         if(par)
  233.             continue;
  234.         if(*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == ',') {
  235.             if(ap != NULLCHAR)
  236.                 break;
  237.             continue;
  238.         }
  239.         if(ap == NULLCHAR)
  240.             ap = cp;
  241.     }
  242.     *cp = '\0';
  243.     return ap;
  244. }
  245.  
  246.  
  247. char *Hdrs[] = {
  248.     "Approved: ",
  249.     "From: ",
  250.     "To: ",
  251.     "Date: ",
  252.     "Message-Id: ",
  253.     "Subject: ",
  254.     "Received: ",
  255.     "Sender: ",
  256.     "Reply-To: ",
  257.     "Status: ",
  258.     "X-BBS-Msg-Type: ",
  259.     "X-Forwarded-To: ",
  260.     "Cc: ",
  261.     "Return-Receipt-To: ",
  262.     "Apparently-To: ",
  263.     "Errors-To: ",
  264.     "Organization: ",
  265.     "Newsgroup: ",
  266.     "Path: ",
  267.     "X-BBS-Hold: ",
  268.     NULLCHAR,
  269. };
  270.  
  271.  
  272. /* return the header type */
  273. int
  274. htype(s)
  275. char *s;
  276. {
  277.     register char *p;
  278.     register int i;
  279.  
  280.     p = s;
  281.     /* check to see if there is a ':' before and white space */
  282.     while (*p != '\0' && *p != ' ' && *p != ':')
  283.         p++;
  284.     if (*p != ':')
  285.         return NOHEADER;
  286.  
  287.     for (i = 0; Hdrs[i] != NULLCHAR; i++) {
  288.         if (strnicmp(Hdrs[i],s,strlen(Hdrs[i])) == 0)
  289.             return i;
  290.     }
  291.     return UNKNOWN;
  292. }
  293.  
  294.  
  295. /* Read the rewrite file for lines where the first word is a regular
  296.  * expression and the second word are rewriting rules. The special
  297.  * character '$' followed by a digit denotes the string that matched
  298.  * a '*' character. The '*' characters are numbered from 1 to 9.
  299.  * Example: the line "*@*.* $2@$1.ampr.org" would rewrite the address
  300.  * "foo@bar.xxx" to "bar@foo.ampr.org".
  301.  * $H is replaced by our hostname, and $$ is an escaped $ character.
  302.  * If the third word on the line has an 'r' character in it, the function
  303.  * will recurse with the new address.
  304.  */
  305. char *
  306. rewrite_address(addr)
  307. char *addr;
  308. {
  309.     char *argv[10], buf[PLINELEN], *cp, *cp2, *retstr;
  310.     int cnt;
  311.     FILE *fp;
  312.  
  313.     if ((fp = fopen(Rewritefile,READ_TEXT)) == NULLFILE)
  314.         return NULLCHAR;
  315.  
  316.     memset((char *)argv,0,10*sizeof(char *));
  317.     while(fgets(buf,sizeof(buf),fp) != NULLCHAR) {
  318.         if(*buf == '#')        /* skip commented lines */
  319.             continue;
  320.  
  321.         if((cp = strchr(buf,' ')) == NULLCHAR) /* get the first word */
  322.             if((cp = strchr(buf,'\t')) == NULLCHAR)
  323.                 continue;
  324.         *cp = '\0';
  325.         if((cp2 = strchr(buf,'\t')) != NULLCHAR){
  326.             *cp = ' ';
  327.             cp = cp2;
  328.             *cp = '\0';
  329.         }
  330.         if(!wildmat(addr,buf,argv))
  331.             continue;        /* no match */
  332.         rip(++cp);
  333.         /* scan past additional whitespaces */
  334.         while (*cp == ' ' || *cp == '\t') ++cp;
  335.         cp2 = retstr = (char *) callocw(1,PLINELEN);
  336.         while(*cp != '\0' && *cp != ' ' && *cp != '\t')
  337.             if(*cp == '$') {
  338.                 if(isdigit(*(++cp)))
  339.                     if(argv[*cp - '0'-1] != '\0')
  340.                         strcat(cp2,argv[*cp - '0'-1]);
  341.                 if(*cp == 'h' || *cp == 'H') /* Our hostname */
  342.                     strcat(cp2,Hostname);
  343.                 if(*cp == '$')    /* Escaped $ character */
  344.                     strcat(cp2,"$");
  345.                 cp2 = retstr + strlen(retstr);
  346.                 cp++;
  347.             }
  348.             else
  349.                 *cp2++ = *cp++;
  350.         for(cnt=0; argv[cnt] != NULLCHAR; ++cnt)
  351.             free(argv[cnt]);
  352.         fclose(fp);
  353.         /* If there remains an 'r' character on the line, repeat
  354.          * everything by recursing.
  355.          */
  356.         if(strchr(cp,'r') != NULLCHAR || strchr(cp,'R') != NULLCHAR) {
  357.             if((cp2 = rewrite_address(retstr)) != NULLCHAR) {
  358.                 free(retstr);
  359.                 return cp2;
  360.             }
  361.         }
  362.         return retstr;
  363.     }
  364.     fclose(fp);
  365.     return NULLCHAR;
  366. }
  367.  
  368.